// 函子 ---> 容器

// 作业三
const fp = require('lodash/fp')
class Container {
  static of(value) {
    return new Container(value)
  }
  constructor(value) {
    this._value = value
  }
  map(fn) {
    return Container.of(fn(this._value))
  }
}
class Maybe {
  static of(x) {
    return new Maybe(x)
  }
  isNothing() {
    return this._value === null || this._value === undefined
  }
  constructor(x) {
    this._value = x
  }
  map(fn) {
    return this.isNothing() ? this : Maybe.of(fn(this._value))
  }
}
// 练习1
// 使用fp.add(x, y)和fp.map(f, x)创建一个能让functor里的值增加的函数ex1
let maybe = Maybe.of([5, 6, 1])
let ex1 = (n) => {
  return maybe.map(array => fp.map(fp.add(n), array))
}
console.log(ex1()._value)

// 练习2
// 实现一个函数ex2，能够使用fp.first获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do'])
let ex2 = () => {
  return xs.map(fp.first)
}
console.log(ex2()._value)

// 练习3
// 实现一个函数ex3,使用safeProp 和 fp.first 找到user的名字的首字母
let safeProp = fp.curry(function (x, o) {
  return Maybe.of(o[x])
})
let user = { id: 2, name: 'Albert' }
let ex3 = () => {
  return safeProp('name')(user).map(fp.first)
}
console.log(ex3()._value)

// 练习4
// 使用Maybe重写ex4，不要有if语句
// let ex4 = function (n) {
//   if (n) {
//     return parseInt(n)
//   }
// }
let ex4 = n => Maybe.of(n).map(parseInt)
console.log(ex4(Math.PI)._value)
